"""
@Author : 合肥一元数智教育科技有限公司
@Date :  2025/6/5 8:35
@Description : 
线程和进程
进程:  系统资源的最小分配单位，通俗理解一个正在运行的程序就是一个进程，比如：QQ，微信  QQ音乐
线程:  程序执行的最小单位，实际进程只负责分配资源，实际执行任务的还是线程，也就是说进程是线程的容器，
       一个进程中至少有一个线程来执行任务，线程自己不分配资源，它和同一个进程中的其它线程共享进程中的资源
并发： 在一段时间内交替执行多个任务，例如：在单核的cpu上执行多个任务，操作系统会轮流执行多个任务，任务的数量大于cpu的核心数
并行: 在一段时间内同时执行多个任务，例如:在多核cpu上执行多个任务，操作系统会给cpu的每个核分别分配任务，多个任务同时执行
"""
import os
import time
import multiprocessing  # 进程模块


# 唱歌
def sing(num):
    print(f'执行sing程序的进程号是:{os.getpid()},父进程的ID{os.getppid()}')
    for i in range(num):
        time.sleep(0.5)
        print('------sing-----')


# 跳舞
def dance(num):
    print(f'执行dance程序的进程号是:{os.getpid()},父进程的ID{os.getppid()}')
    for i in range(num):
        time.sleep(1)
        print('------dance-----')


"""
  默认情况:  运行一个程序  系统会开辟一个进程  在进程中默认会包含一个线程  
  并发执行    抢占cpu的运行时间  0.1s   sing  2  停止  dance 0.5  5   
  sing()    自定义进程1    线程
  dance()   自定义进程2    线程

默认情况: 主进程的执行需要等待子进程执行结束后才会真正结束

设置守护进程  主进程任务结束，子进程会被强制停止
"""
# 进程  分配资源    主线程
if __name__ == '__main__':
    print(f'执行main程序的进程号是:{os.getpid()}')
    # 创建进程实例   args 进程使用时 完成参数传递  () 传递参数时  需要注意参数的位置  位置参数
    mp1 = multiprocessing.Process(target=sing, args=(3,))
    # kwargs 以关键词的形式进行参数传递  key 需要和函数中的形参保持一致
    mp2 = multiprocessing.Process(target=dance,kwargs={'num':5})
    # 在启动之前设置守护进程
    # mp1.daemon = True
    # mp2.daemon = True
    # 启动进程  开始执行任务
    mp1.start()
    mp2.start()
    print('-------------主进程任务结束--------------')
